////////////////////////////////////////////////////////////////////////////
//
//  Crytek Engine Source File.
//  Copyright (C), Crytek Studios, 2002.
// -------------------------------------------------------------------------
//  File name:   ObjectMode.h
//  Version:     v1.00
//  Created:     18/11/2004 by Timur.
//  Compilers:   Visual Studio.NET
//  Description: Object edit mode describe viewport input behavior when operating on objects.
// -------------------------------------------------------------------------
//  History:
//
////////////////////////////////////////////////////////////////////////////

#ifndef __ObjectMode_h__
#define __ObjectMode_h__
#pragma once

#include "AI\AIMoveSimulation.h"

// {87109FED-BDB5-4874-936D-338400079F58}
DEFINE_GUID( OBJECT_MODE_GUID, 0x87109fed, 0xbdb5, 0x4874, 0x93, 0x6d, 0x33, 0x84, 0x0, 0x7, 0x9f, 0x58);


class CBaseObject;
class CDeepSelection;
/*!
*	CObjectMode is an abstract base class for All Editing	Tools supported by Editor.
*	Edit tools handle specific editing modes in viewports.
*/
class CObjectMode : public CEditTool
{
public:
	DECLARE_DYNCREATE(CObjectMode);

	CObjectMode();
	virtual ~CObjectMode();

	// Registration function.
	static void RegisterTool( CRegistrationContext &rc );

	//////////////////////////////////////////////////////////////////////////
	// CEditTool implementation.
	//////////////////////////////////////////////////////////////////////////
	virtual void BeginEditParams( IEditor *ie,int flags ) {};
	virtual void EndEditParams() {};
	virtual void Display( struct DisplayContext &dc );
	virtual void DisplaySelectionPreview( struct DisplayContext &dc );
	virtual void DrawSelectionPreview( struct DisplayContext &dc , CBaseObject *drawObject);
	void DisplayExtraLightInfo( struct DisplayContext &dc );
	
	virtual bool MouseCallback( CViewport *view,EMouseEvent event,CPoint &point,int flags );
	virtual bool OnKeyDown( CViewport *view,uint32 nChar,uint32 nRepCnt,uint32 nFlags );
	virtual bool OnKeyUp( CViewport *view,uint32 nChar,uint32 nRepCnt,uint32 nFlags );
	virtual bool OnSetCursor( CViewport *vp ) { return false; };

	virtual void OnManipulatorDrag( CViewport *view,ITransformManipulator *pManipulator,CPoint &p0,CPoint &p1,const Vec3 &value );

protected:
	enum ECommandMode
	{
		NothingMode = 0,
		ScrollZoomMode,
		SelectMode,
		MoveMode,
		RotateMode,
		ScaleMode,
		ScrollMode,
		ZoomMode,
	};

	bool OnLButtonDown( CViewport *view,int nFlags, CPoint point );
	bool OnLButtonDblClk( CViewport *view,int nFlags, CPoint point);
	bool OnLButtonUp( CViewport *view,int nFlags, CPoint point );
	bool OnRButtonDown( CViewport *view,int nFlags, CPoint point );
	bool OnRButtonUp( CViewport *view,int nFlags, CPoint point );
	bool OnMButtonDown( CViewport *view,int nFlags, CPoint point );
	bool OnMouseMove( CViewport *view,int nFlags, CPoint point );

	bool CheckVirtualKey( int virtualKey );
	void SetCommandMode( ECommandMode mode ) { m_commandMode = mode; }
	ECommandMode GetCommandMode() const { return m_commandMode; }

	//! Ctrl-Click in move mode to move selected objects to given pos.
	void MoveSelectionToPos( CViewport *view, Vec3 &pos, bool align );
	void SetObjectCursor( CViewport *view,CBaseObject *hitObj,bool bChangeNow=false );

	virtual void DeleteThis() { delete this; };

	void UpdateStatusText();
	void AwakeObjectAtPoint( CViewport *view,CPoint point );

	void HideMoveByFaceNormGizmo();
	void HandleMoveByFaceNormal( HitContext& hitInfo );
	void UpdateMoveByFaceNormGizmo( CBaseObject *pHitObject );

private:
	void	CheckDeepSelection(HitContext& hitContext, CWnd* pWnd);
	Vec3& GetScale( const CViewport *view, const CPoint& point, Vec3& OutScale );

	CPoint m_cMouseDownPos;
	ECommandMode m_commandMode;

	CAIMoveSimulation m_AIMoveSimulation;

	GUID m_MouseOverObject;
	bool m_openContext;
	typedef std::vector<GUID> TGuidContainer;
	TGuidContainer m_PreviewGUIDs;

	_smart_ptr<CDeepSelection> m_pDeepSelection;

	bool m_bMoveByFaceNormManipShown;
	CBaseObject *m_pHitObject;
};



#endif //__ObjectMode_h__
